package spring.context.servlet;

import org.apache.commons.lang3.StringUtils;
import spring.annotations.AnnotationInitListener;
import spring.context.ApplicationContextHolder;
import spring.context.ConfigurableWebApplicationContext;
import spring.exceptions.BeanInitializationException;
import spring.factory.BeanFactory;
import spring.factory.WebApplicationBeanFactory;
import spring.webmvc.ContextLoader;
import utils.LogUtils;

import javax.servlet.ServletContext;

public class SimpleWebApplicationContext implements ConfigurableWebApplicationContext {


    public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
    private final WebApplicationBeanFactory beanFactory;
    private ServletContext servletContext;

    public SimpleWebApplicationContext(ServletContext servletContext) {
        this.beanFactory = new WebApplicationBeanFactory();
        setServletContext(servletContext);
        ApplicationContextHolder.register(beanFactory);
    }

    @Override
    public String getApplicationName() {
        return (this.servletContext != null ? this.servletContext.getContextPath() : "");
    }

    @Override
    public BeanFactory getBeanFactory() throws IllegalStateException {
        return this.beanFactory;
    }

    @Override
    public void initialApplicationContext() {
        String locationStr = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
        if (StringUtils.isNotBlank(locationStr)) {
            initialFromXml(locationStr);
        } else {
            locationStr = servletContext.getInitParameter(ContextLoader.ANNOTATION_NAME);
            initialFromAnnotation(locationStr);
        }
    }

    private void initialFromXml(String locationStr) {
        String[] locations = locationStr.split(";");
        if (locations.length == 0) {
            return;
        }
        LogUtils.info("开始初始化配置文件");
        String[] configLocations = new String[locations.length];
        for (int i = 0; i < locations.length; i++) {
            String location = locations[i].trim()
                    .replaceAll("\n", "")
                    .replaceAll("\t", "");
            if (StringUtils.isNotBlank(location)) {
                configLocations[i] = location;
            }
        }
        beanFactory.parseXml(configLocations);

    }

    private void initialFromAnnotation(String listenerClass) {
        Class<?> configClass;
        try {
            configClass = Class.forName(listenerClass);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BeanInitializationException("注解解析异常，请确定注册的项目配置文件类型有效");
        }
        AnnotationInitListener annotationInit = new AnnotationInitListener();
        annotationInit.init(beanFactory, configClass);
    }

    @Override
    public ServletContext getServletContext() {
        return this.servletContext;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Override
    public <T> T getBean(String beanId) {
        return beanFactory.getBean(beanId);
    }
}
